﻿//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Exception Handling Application Block
//===============================================================================

using System;
using System.ComponentModel;
using System.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ContainerModel;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Design;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration;

namespace EntLibContrib.ExceptionHandling.Configuration
{
	/// <summary>
	/// Represents the configuration data for a <see cref="SqlExceptionWrapHandler"/>.
	/// </summary>
    [ResourceDescription(typeof(DesignResources), "SqlExceptionWrapHandlerDataDescription")]
    [ResourceDisplayName(typeof(DesignResources), "SqlExceptionWrapHandlerDataDisplayName")]
	public class SqlExceptionWrapHandlerData : ExceptionHandlerData
	{
		#region Fields
		private static AssemblyQualifiedTypeNameConverter typeConverter = new AssemblyQualifiedTypeNameConverter();
		private const string errorCodesProperty = "errorCodes";
		private const string exceptionMessageProperty = "defaultExceptionMessage";
		private const string wrapExceptionTypeProperty = "defaultWrapExceptionType";
		private const string errorCodeNotConfiguredBehaviorPropertyName = "errorCodeNotConfiguredBehavior";
		#endregion

		#region Construction
		/// <summary>
		/// Initializes a new instance of the <see cref="SqlExceptionWrapHandlerData"/> class.
		/// </summary>
		public SqlExceptionWrapHandlerData() : base(typeof(SqlExceptionWrapHandler))
		{
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="SqlExceptionWrapHandlerData"/> class.
		/// </summary>
		/// <param name="name">The name.</param>
		/// <param name="errorCodeNotConfiguredBehavior">The error code not configured behavior.</param>
		/// <param name="defaultExceptionMessage">The default exception message.</param>
		/// <param name="defaultWrapExceptionTypeName">Default name of the wrap exception type.</param>
		/// <param name="errorCodes">The error codes.</param>
		public SqlExceptionWrapHandlerData(string name, ErrorCodeNotConfiguredBehavior errorCodeNotConfiguredBehavior, string defaultExceptionMessage, string defaultWrapExceptionTypeName, NamedElementCollection<ErrorCodeEntryData> errorCodes)
			: base(name, typeof(SqlExceptionWrapHandler))
		{
			this.ErrorCodeNotConfiguredBehavior = errorCodeNotConfiguredBehavior;
			this.DefaultExceptionMessage = defaultExceptionMessage;
			this.DefaultWrapExceptionTypeName = defaultWrapExceptionTypeName;
			this.ErrorCodes = errorCodes;
		}
		#endregion

		#region Properties
		/// <summary>
		/// Gets or sets the default exception message.
		/// </summary>
		/// <value>The default exception message.</value>
		[ConfigurationProperty(exceptionMessageProperty, IsRequired = false)]
		public string DefaultExceptionMessage
		{
			get { return (string)this[exceptionMessageProperty]; }
			set { this[exceptionMessageProperty] = value; }
		}

		/// <summary>
		/// Gets or sets the type of the replacement exception.
		/// </summary>
		/// <value>The default type of the wrap exception.</value>
		public Type DefaultWrapExceptionType
		{
			get { return (Type)typeConverter.ConvertFrom(DefaultWrapExceptionTypeName); }
			set { DefaultWrapExceptionTypeName = typeConverter.ConvertToString(value); }
		}

		/// <summary>
		/// Gets or sets the fully qualified type name of the replacement exception.
		/// </summary>
		/// <value>The fully qualified type name of the replacement exception.</value>
		[ConfigurationProperty(wrapExceptionTypeProperty, IsRequired = true)]
        [Editor(CommonDesignTime.EditorTypes.TypeSelector, CommonDesignTime.EditorTypes.UITypeEditor)]
        [BaseType(typeof(Exception))]
        public string DefaultWrapExceptionTypeName
		{
			get { return (string)this[wrapExceptionTypeProperty]; }
			set { this[wrapExceptionTypeProperty] = value; }
		}

		/// <summary>
		/// Gets or sets the error codes.
		/// </summary>
		/// <value>The error codes.</value>
		[ConfigurationProperty(errorCodesProperty)]
		public NamedElementCollection<ErrorCodeEntryData> ErrorCodes
		{
			get { return (NamedElementCollection<ErrorCodeEntryData>)base[errorCodesProperty]; }
			private set { base[errorCodesProperty] = value; }
		}

		/// <summary>
		/// Gets or sets the error code not configured behavior.
		/// </summary>
		/// <value>The error code not configured behavior.</value>
		[ConfigurationProperty(errorCodeNotConfiguredBehaviorPropertyName)]
		public ErrorCodeNotConfiguredBehavior ErrorCodeNotConfiguredBehavior
		{
			get { return (ErrorCodeNotConfiguredBehavior)this[errorCodeNotConfiguredBehaviorPropertyName]; }
			set { this[errorCodeNotConfiguredBehaviorPropertyName] = value; }
		}
		#endregion

        /// <summary>
        /// Get the set of <see cref="TypeRegistration"/> objects needed to
        /// register the matching rule represented by this config element and its associated objects.
        /// </summary>
        /// <param name="namePrefix">The name to use when building references to child items.</param>
        /// <returns>The set of <see cref="TypeRegistration"/> objects.</returns>
        public override System.Collections.Generic.IEnumerable<TypeRegistration> GetRegistrations(string namePrefix)
        {
            yield return
                new TypeRegistration<IExceptionHandler>(
                    () => new SqlExceptionWrapHandler(this))
                {
                    Name = BuildName(namePrefix),
                    Lifetime = TypeRegistrationLifetime.Transient
                };
        }
	}
}